#include "LinkedList.h"

void enqueue(queue_t* &unitQueue, int data, coordinate_t point) {
	node* queueFront = unitQueue->front;
	node* queueRear = unitQueue->rear;

	node* queueNode = (node*) malloc(sizeof(node));

	queueNode->prev = queueRear->prev;
	queueNode->next = queueRear;

	queueRear->prev->next = queueNode;
	queueRear->prev = queueNode;

	queueNode->data = data;
	queueNode->point.x = point.x;
	queueNode->point.y = point.y;
	unitQueue->length++;
}

int dequeue(queue_t* &unitQueue) {
	node* queueFront = unitQueue->front;
	node* queueRear = unitQueue->rear;

	node* deQueueNode;

	int data;
	if (queueFront->next != queueRear && unitQueue->length > 0){
		deQueueNode = queueFront->next;

		queueFront->next = deQueueNode->next;
		deQueueNode->next->prev = queueFront;

		data = deQueueNode->data;

		free(deQueueNode);
		unitQueue->length--;
		return data;
	}
	else {
		//printf("queue is empty\n");
		return -1;
	}

}

/*
	how to use  :
	queue_t* unitQueue = NULL;
	initQueue(unitQueue);

	and then... enqueue(...), dequeue(...)

	unitqueue->length is queue's length
	*/
void initQueue(queue_t* &unitQueue) {
	unitQueue = (queue_t*) malloc(sizeof(queue_t));

	node* queueFront = (node*) malloc(sizeof(node));
	node* queueRear = (node*) malloc(sizeof(node));
	unitQueue->length = 0;

	queueFront->next = queueRear;
	queueFront->prev = NULL;
	queueRear->next = NULL;
	queueRear->prev = queueFront;

	unitQueue->front = queueFront;
	unitQueue->rear = queueRear;
}

/* free memory */
void freeQueue(queue_t* &unitQueue) {
	/* check queue is empty */
	if (unitQueue->length == 0) {
		free(unitQueue->front);
		free(unitQueue->rear);
		free(unitQueue);
	}
	else {
		while (dequeue(unitQueue) != -1)
		{
		}
		free(unitQueue->front);
		free(unitQueue->rear);
		free(unitQueue);
	}
}

/*
	index : negative infinite ... 0 ... queue's length ... postive inifinite

	if queue's length is 8;
	nodeAtQueue(unitQueue, 7);
	nodeAtQueue(unitQueue, -1);
	nodeAtQueue(unitQueue, 99);

	above cases are possible
	*/

node_t* nodeAtQueue(queue_t* &unitQueue, int index) {
	node_t* returnNode = NULL;
	if ( unitQueue->length == 0)
	{
		return returnNode;
	}

	/* index is greater than queue's length */
	if (index >= unitQueue->length)
	{
		index %= unitQueue->length;
		returnNode = unitQueue->front->next;
		while (index > 0)
		{
			returnNode = returnNode->next;
			index--;
		}
	}/* index is less than 0 */
	else if (index < 0)
	{
		returnNode = unitQueue->rear->prev;
		while (index < 0)
		{
			returnNode = returnNode->prev;
			index++;
		}

	}/* index is in between 0 and queue's length */
	else
	{
		returnNode = unitQueue->front->next;
		while (index > 0)
		{
			returnNode = returnNode->next;
			index--;
		}
	}

	return returnNode;

}
